package org.millioncall.yueyoga.admin.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.millioncall.openplatform.common.PaginatedList;
import org.millioncall.openplatform.util.StringUtils;
import org.millioncall.yueyoga.admin.dao.AreaDAO;
import org.millioncall.yueyoga.admin.dao.EarlyExperienceDAO;
import org.millioncall.yueyoga.admin.dao.MemberDAO;
import org.millioncall.yueyoga.admin.dao.MemberLevelDAO;
import org.millioncall.yueyoga.admin.dao.RemainingDAO;
import org.millioncall.yueyoga.admin.dao.StatusDAO;
import org.millioncall.yueyoga.admin.dao.UserDetailDAO;
import org.millioncall.yueyoga.admin.model.AviatorExpression;
import org.millioncall.yueyoga.admin.model.ClassMemberModel;
import org.millioncall.yueyoga.admin.model.EarlyExperience;
import org.millioncall.yueyoga.admin.model.Member;
import org.millioncall.yueyoga.admin.model.MemberAdvance;
import org.millioncall.yueyoga.admin.model.MemberLevel;
import org.millioncall.yueyoga.admin.model.MemberModel;
import org.millioncall.yueyoga.admin.model.UserDetail;
import org.millioncall.yueyoga.admin.service.MemberService;
import org.millioncall.yueyoga.admin.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MemberServiceImpl implements MemberService {
	private static final Logger logger = LoggerFactory
			.getLogger(MemberLevel.class);

	private MemberDAO memberDAO;
	private AreaDAO areaDAO;
	private MemberLevelDAO memberLevelDAO;
	private UserService userService;
	private UserDetailDAO userDetailDAO;
	private EarlyExperienceDAO earlyExperienceDAO;
	private RemainingDAO remainingDAO;
	private StatusDAO statusDAO;

	public MemberDAO getMemberDAO() {
		return memberDAO;
	}

	public void setMemberDAO(MemberDAO memberDAO) {
		this.memberDAO = memberDAO;
	}

	@Override
	public PaginatedList<Member> getMemberInPage(int start, int pageSize) {
		PaginatedList<Member> p = memberDAO.findPage(start, pageSize);
		return p;
	}

	@Override
	public List<Member> getMemberAll(Map<String, Object> map) {
		List<Member> p = memberDAO.getMemberAll(map);
		return p;
	}

	@Override
	public boolean saveMember(Map<String, Object> map) {
		try {
			memberDAO.save(map);
			Long memberId = (Long)map.get("memberId");
			EarlyExperience earlyExperience = new EarlyExperience();
			earlyExperience.setMemberId(memberId.intValue());
			earlyExperience.setDemoclass(false);
			earlyExperience.setPlacementtest(false);
			earlyExperience.setTrialclass(false);
			earlyExperience.setVisit(false);
			earlyExperienceDAO.insert(earlyExperience);
			
			Map<String,Object> remainParams = new HashMap<String,Object>();
			remainParams.put("memberId", memberId);
			remainParams.put("remaining", 0);
			remainParams.put("score", 0);
			this.remainingDAO.save(remainParams);
			
			return true;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public void deleteMemberByIds(Integer[] deids) {
		if (deids == null || deids.length == 0) {
			logger.error("未提交要删除会员的编号");
			throw new RuntimeException(" 未提交要删除会员的编号");
		} else {
			this.memberDAO.deleteByIds(deids);
		}
	}

	@Override
	public Member findByCardNumber(Map<String, Object> map) {
		return this.memberDAO.findByCardNumber(map);
	}

	@Override
	public void editMemberEnblue(Integer[] deids, Map<String, Object> map) {
		if (deids == null || deids.length == 0) {
			logger.error("未提交要修改会员的编号");
			throw new RuntimeException(" 未提交要修改会员的编号");
		} else {
			this.memberDAO.editMemberEnblue(deids, map);
		}
	}

	@Override
	public PaginatedList<Member> getMemberInPage(int start, int pageSize,
			String[] paramNames, String[] paramValues) {
		Map<String, Object> map = new HashMap<String, Object>();
		for (int i = 0; i < paramNames.length; i++) {
			map.put("paramName", paramNames[i]);
			String paramValue = "";
			try {
				paramValue = new String(paramValues[i].getBytes("iso8859-1"),
						"UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			map.put("paramValue", paramValue);
		}
		PaginatedList<Member> p = memberDAO.findPage(start, pageSize, map);
		return p;
	}

	@Override
	public Member findById(Map<String, Object> map) {
		Member member = this.memberDAO.findById(map);
		if (member != null) {
			if (member.getLevelId() != null) {
				member.setLevel(memberLevelDAO.findById(member.getLevelId()));
			}
			if (member.getArea() != null && member.getArea().getAreaId() != 0) {
				member.setArea(areaDAO.findAreaById(member.getArea()
						.getAreaId()));
			}
			if (StringUtils.isNotBlank(member.getKeeperId())) {
				member.setKeeper(userService.findById(member.getKeeperId()));
			}
			if (StringUtils.isNotBlank(member.getPromoterId())) {
				member.setPromoter(userService.findById(member.getPromoterId()));
			}
		}
		return this.memberDAO.findById(map);
	}

	@Override
	public void editMemberCardNumber(Map<String, Object> map) {
		this.memberDAO.editMemberCardNumber(map);
	}

	@Override
	public List<Member> findMemberByProperty(Map<String, Object> map) {
		return this.memberDAO.findMemberByProperty(map);
	}

	@Override
	public List<Member> findMemberByCardNumberOrPhone(Object value) {
		return this.memberDAO.findMemberByCardNumberOrPhone(value);
	}

	@Override
	public PaginatedList<Member> getMemberInPage(int start, int pageSize,
			Map<String, Object> map) {
		return this.memberDAO.findPage(start, pageSize, map);
	}

	@Override
	public boolean updateMember(Member member) {
		int i = memberDAO.update(member);
		if (i > 0) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public int findByMaxId() {
		return this.memberDAO.findByMaxId();
	}

	@Override
	public Member findByPhone(Map<String, Object> map1) {
		return this.memberDAO.findByPhone(map1);
	}

	public MemberLevelDAO getMemberLevelDAO() {
		return memberLevelDAO;
	}

	public void setMemberLevelDAO(MemberLevelDAO memberLevelDAO) {
		this.memberLevelDAO = memberLevelDAO;
	}

	public AreaDAO getAreaDAO() {
		return areaDAO;
	}

	public void setAreaDAO(AreaDAO areaDAO) {
		this.areaDAO = areaDAO;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Override
	public List<ClassMemberModel> findAllBasicMemberInfo(Map<String, Object> map) {
		return this.memberDAO.findAllBasicMembers(map);
	}

	@Override
	public PaginatedList<Member> findMemberByLiftClubId(int start, int limit,
			Map<String, Object> map) {
		return this.memberDAO.findMemberByLiftClubId(start, limit, map);
	}

	public EarlyExperienceDAO getEarlyExperienceDAO() {
		return earlyExperienceDAO;
	}

	public void setEarlyExperienceDAO(EarlyExperienceDAO earlyExperienceDAO) {
		this.earlyExperienceDAO = earlyExperienceDAO;
	}

	public RemainingDAO getRemainingDAO() {
		return remainingDAO;
	}

	public void setRemainingDAO(RemainingDAO remainingDAO) {
		this.remainingDAO = remainingDAO;
	}

	@Override
	public List<Member> findAllMember(Map<String, Object> map) {
		return this.memberDAO.findAllMember(map);
	}

	@Override
	public PaginatedList<Member> findAllMemberByGroup(Integer start,
			Integer limit, Integer groupId) {
		return this.memberDAO.findAllMemberByGroup(start, limit, groupId);
	}

	public String findKeeperId(String organizationId, String name) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("organizationId", organizationId);
		map.put("name", name);
		map.put("groupName", "keepers");
		UserDetail userDetail = userDetailDAO.findUserDetailByName(map);
		String id = "";
		if (userDetail == null) {
			return "";
		} else {
			id = userDetail.getId();
		}
		return id;
	}

	public String getStatusCode(int type, String name) {
		if (StringUtils.isNotBlank(name)) {
			return this.statusDAO.findCodeByTypeName(type, name);
		}
		return "";
	}

	public UserDetailDAO getUserDetailDAO() {
		return userDetailDAO;
	}

	public void setUserDetailDAO(UserDetailDAO userDetailDAO) {
		this.userDetailDAO = userDetailDAO;
	}

	public StatusDAO getStatusDAO() {
		return statusDAO;
	}

	public void setStatusDAO(StatusDAO statusDAO) {
		this.statusDAO = statusDAO;
	}

	@Override
	public List<Member> findExpireBirthdayMember() {
		return this.memberDAO.findExpireBirthdayMember();
	}

	/**
	 * 会员导入
	 */
	@Override
	public String importMemberFromExcel(File source, Map<String, Object> map) {
		FileInputStream inStream = null;
		XSSFWorkbook workbook = null;
		String msg = "0#会员信息导入失败!";
		try {
			inStream = new FileInputStream(source);
			workbook = new XSSFWorkbook(inStream);
		} catch (Exception e) {
			logger.error("导入excel数据时异常", e);
			return "1#导入excel数据时异常!";
		}

		XSSFSheet sheet = workbook.getSheetAt(0);
		Iterator<Row> row = sheet.rowIterator();
		// 标题
		Row title = row.next();
		// 验证列名未被修改或移动
		for (Iterator<Cell> iterator = title.iterator(); iterator.hasNext();) {
			Cell cell = iterator.next();
			if (cell.getCellType() != Cell.CELL_TYPE_STRING) {
				logger.error("导入出错，单元格的格式必须为字符串");
				return "2#导入出错，单元格的格式必须为字符串";
			}
		}

		List<Member> saveList = new ArrayList<Member>();
		// 验证列
		if (!row.hasNext()) {
			logger.error("没有需要导入的数据");
			return "3#没有需要导入的数据!";
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String tmpVal = null;
		while (row.hasNext()) {
			Member member = new Member();

			Row rown = row.next();
			// 行的所有列
			Iterator<Cell> cellbody = rown.cellIterator();
			int k = 0;

			// 遍历一行的列
			while (cellbody.hasNext()) {
				Cell cell = cellbody.next();
				k = cell.getColumnIndex();
				switch (k) {
				case 0:// 会员编号，卡号
					tmpVal = cell.getStringCellValue();
					member.setCardnumber(tmpVal);
					break;
				case 1:// 姓名
					tmpVal = cell.getStringCellValue();
					member.setName(tmpVal);
					break;
				case 2:// 手机号
					tmpVal = cell.getStringCellValue();
					member.setPhone(tmpVal);
					break;
				case 3:// 生日
					Date date = null;
					try {
						date = sdf.parse(cell.getStringCellValue());
					} catch (Exception e) {
						date = null;
					}
					if (date != null) {
						member.setBirthday(date);
					}
					break;
				case 4:// 地址
					tmpVal = cell.getStringCellValue();
					member.setAddress(tmpVal);
					break;
				case 5:// 会籍顾问
					tmpVal = cell.getStringCellValue();
					tmpVal = findKeeperId(map.get("organizationId").toString(),
							tmpVal);
					member.setKeeperId(tmpVal);
					break;
				case 6:// 信息来源
					tmpVal = cell.getStringCellValue();
					member.setMarketingsource(getStatusCode(8, tmpVal));
					break;
				case 7:// 子渠道
					tmpVal = cell.getStringCellValue();
					member.setSubmarketingchannel(getStatusCode(5, tmpVal));
					break;
				case 8:// 外卡
					tmpVal = cell.getStringCellValue();
					member.setOutsideCardNo(tmpVal);
					break;
				}
			}
			if (StringUtils.isNotBlank(member.getName())
					&& StringUtils.isNotBlank(member.getPhone())) {
				saveList.add(member);
			}
		}
		try {
			inStream.close();
		} catch (IOException e) {
			logger.error("文件流关闭异常");
			return "4#文件流关闭异常!";
		}

		Map<String, Object> params = new HashMap<String, Object>();
		int existCount = 0;
		int failCount = 0;
		String impInfo = "";
		String failInfo = "";
		for (Member m : saveList) {
			params.put("cardNumber", m.getCardnumber());
			params.put("phone", m.getPhone());
			params.put("groups", map.get("groups"));
			params.put("hallcode", map.get("hallcode"));
			Member mem = memberDAO.findMemberByMemberInfo(params);
			if (mem != null) {
				existCount++;
				impInfo += m.getCardnumber() + "--" + m.getPhone() + "!";
			} else {
				params.put("name", m.getName());
				params.put("birthday", m.getBirthday());
				params.put("address", m.getAddress());
				params.put("keeperId", m.getKeeperId());
				params.put("outside", m.getOutsideCardNo());
				params.put("sex", "女");
				if (StringUtils.isNotBlank(m.getMarketingsource())) {
					String ms = m.getMarketingsource();
					params.put("marketingSource", Integer.valueOf(ms));
				}
				params.put("userId", map.get("userId"));
				params.put("organizationId", map.get("organizationId"));
				boolean flag = this.saveMember(params);
				if (!flag) {
					failCount++;
					failInfo += m.getCardnumber() + "--" + m.getPhone() + "!";
				} else {
					Member member = memberDAO.findMemberByMemberInfo(params);
					EarlyExperience earlyExperience = new EarlyExperience();
					earlyExperience.setMemberId(member.getMemberid());
					earlyExperience.setDemoclass(false);
					earlyExperience.setPlacementtest(false);
					earlyExperience.setTrialclass(false);
					earlyExperience.setVisit(false);
					earlyExperienceDAO.insert(earlyExperience);
					Map<String, Object> map1 = new HashMap<String, Object>();
					map1.put("memberId", member.getMemberid());
					map1.put("remaining", 0);
					map1.put("score", 0);
					remainingDAO.save(map1);
				}
			}
		}
		String str = "0:[]";
		if (StringUtils.isNotBlank(impInfo)) {
			impInfo = existCount + ":["
					+ impInfo.substring(0, impInfo.length() - 1) + "]";
		} else {
			impInfo = str;
		}
		if (StringUtils.isNotBlank(failInfo)) {
			failInfo = failCount + ":["
					+ failInfo.substring(0, failInfo.length() - 1) + "]";
		} else {
			failInfo = str;
		}
		msg = "5#" + saveList.size() + "#[" + (impInfo + "~" + failInfo) + "]";
		return msg;
	}

	@Override
	public List<Member> getAllMembersWithAviator(Map<String, Object> params,
			AviatorExpression expression, Map<String, Object> aviatorParams,
			int limit) {
		return this.memberDAO.getAllMembersWithAviator(params, expression,
				aviatorParams, limit);
	}

	@Override
	public PaginatedList<MemberModel> findFrontMemberList(Integer start,
			Integer limit, Map<String, Object> map) {
		List<String> strs = new ArrayList<String>();
		strs.add("0020");
		strs.add("0021");
		strs.add("0022");
		
		map.put("subStatusGroups", strs);
		String cardOrName = map.get("cardNumber").toString();
		// 有可能是cardId，或者name，或者outsideCardNo
		if (StringUtils.isNotBlank(cardOrName)) {
			map.put("content", "%" + cardOrName + "%");
		}
		PaginatedList<MemberModel> list = memberDAO.findFrontMemberList(start,
				limit, map);
		return list;
	}

	@Override
	public MemberModel findFrontMemberDetailInfo(Map<String, Object> map) {
		return memberDAO.findFrontMemberDetailInfo(map);
	}

	@Override
	public List<MemberAdvance> getAllMembersWithAviatorAdvance(
			Map<String, Object> params, AviatorExpression expression,
			Map<String, Object> aviatorParams, int limit) {
		return this.memberDAO.getAllMembersWithAviatorAdvance(params,
				expression, aviatorParams, limit);
	}

	@Override
	public List<ClassMemberModel> findClassMember(Map<String, Object> map) {
		return this.memberDAO.findClassMember(map);
	}

	@Override
	public int getTotalMembers() {
		return memberDAO.getTotalMembers();
	}

	@Override
	public PaginatedList<MemberModel> findFrontPresentMemberList(Integer start,
			Integer limit, Map<String, Object> map) {
		PaginatedList<MemberModel> list = memberDAO.findFrontPresentMemberList(
				start, limit, map);
		return list;
	}

	@Override
	public PaginatedList<MemberModel> findFrontAbsentMemberList(Integer start,
			Integer limit, Map<String, Object> map) {
		PaginatedList<MemberModel> list = memberDAO.findFrontAbsentMemberList(
				start, limit, map);
		return list;
	}

	@Override
	public boolean updateMemberHeadImg(Map<String, String> params) {
		String memberId = params.get("memberId");
		Member member = this.memberDAO.getSimpleMemberById(memberId);
		if (member == null) {
			return false;
		} else {
			String headImgPath = member.getHeadimgpath();
			if (StringUtils.isNotBlank(headImgPath)) {
				String realPath = params.get("path") + headImgPath;
				File file = new File(realPath);
				if (file.exists()) {
					file.delete();
				}
			}
		}

		try {
			this.memberDAO.updateMemberImg(params);
			return true;
		} catch (Exception e) {
			return false;
		}
	}
}
